// BeyondHello_Interface.java : behavior editor generated Java class
package com.stottlerhenke.simbionic.samples.beyondhello;

import com.stottlerhenke.simbionic.api.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;

public class BeyondHello_Interface extends SB_Interface
{
// sim revision number
	public static final int SIM_REV = 11;

// actions
	public static final int ACTION_BuyFood = 134;
	public static final int ACTION_DriveTo = 132;
	public static final int ACTION_Eat = 133;
	public static final int ACTION_FindNewBulb = 130;
	public static final int ACTION_PackSuitcases = 135;
	public static final int ACTION_Print = 128;
	public static final int ACTION_ReloadCamera = 137;
	public static final int ACTION_ScrewInBulb = 131;
	public static final int ACTION_TakePhoto = 136;
	public static final int ACTION_UnscrewBulb = 129;

// predicates
	public static final int PRED_ComplementaryColor = 128;
	public static final int PRED_FindNearest = 131;
	public static final int PRED_FridgeContents = 129;
	public static final int PRED_GetLocation = 134;
	public static final int PRED_Grade = 132;
	public static final int PRED_MyId = 133;
	public static final int PRED_NeededDocument = 135;
	public static final int PRED_OutOfFilm = 130;
	
	private Vector _entityMeals = new Vector();
	private Vector _entityFilm = new Vector();

	public BeyondHello_Interface()
	{
	}

	public String getModuleName()
	{
		return "BeyondHello";
	}

	public ArrayList getModuleActions()
	{
		ArrayList actions = new ArrayList();

		SB_FuncSpec fs;
		SB_FuncParamSpec fps;
		ArrayList params;

		// BuyFood
		params = new ArrayList();
		fps = new SB_FuncParamSpec("food", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("BuyFood", 134, SB_VarType.kInvalid, params);
		actions.add(fs);

		// DriveTo
		params = new ArrayList();
		fps = new SB_FuncParamSpec("destination", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("DriveTo", 132, SB_VarType.kInvalid, params);
		actions.add(fs);

		// Eat
		params = new ArrayList();
		fs = new SB_FuncSpec("Eat", 133, SB_VarType.kInvalid, params);
		actions.add(fs);

		// FindNewBulb
		params = new ArrayList();
		fs = new SB_FuncSpec("FindNewBulb", 130, SB_VarType.kInvalid, params);
		actions.add(fs);

		// PackSuitcases
		params = new ArrayList();
		fs = new SB_FuncSpec("PackSuitcases", 135, SB_VarType.kInvalid, params);
		actions.add(fs);

		// Print
		params = new ArrayList();
		fps = new SB_FuncParamSpec("message", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("Print", 128, SB_VarType.kInvalid, params);
		actions.add(fs);

		// ReloadCamera
		params = new ArrayList();
		fs = new SB_FuncSpec("ReloadCamera", 137, SB_VarType.kInvalid, params);
		actions.add(fs);

		// ScrewInBulb
		params = new ArrayList();
		fps = new SB_FuncParamSpec("whichBulb", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fps);
		fs = new SB_FuncSpec("ScrewInBulb", 131, SB_VarType.kInvalid, params);
		actions.add(fs);

		// TakePhoto
		params = new ArrayList();
		fps = new SB_FuncParamSpec("target", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("TakePhoto", 136, SB_VarType.kInvalid, params);
		actions.add(fs);

		// UnscrewBulb
		params = new ArrayList();
		fps = new SB_FuncParamSpec("whichBulb", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fps);
		fs = new SB_FuncSpec("UnscrewBulb", 129, SB_VarType.kInvalid, params);
		actions.add(fs);

		return actions;
	}

	public ArrayList getModulePredicates()
	{
		ArrayList preds = new ArrayList();

		SB_FuncSpec fs;
		SB_FuncParamSpec fps;
		ArrayList params;

		// ComplementaryColor : string
		params = new ArrayList();
		fps = new SB_FuncParamSpec("color", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("ComplementaryColor", 128, SB_VarType.kString, params);
		preds.add(fs);

		// FindNearest : vector
		params = new ArrayList();
		fps = new SB_FuncParamSpec("whatToFind", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fps);
		fs = new SB_FuncSpec("FindNearest", 131, SB_VarType.kVector, params);
		preds.add(fs);

		// FridgeContents : string
		params = new ArrayList();
		fs = new SB_FuncSpec("FridgeContents", 129, SB_VarType.kString, params);
		preds.add(fs);

		// GetLocation : string
		params = new ArrayList();
		fs = new SB_FuncSpec("GetLocation", 134, SB_VarType.kString, params);
		preds.add(fs);

		// Grade : integer
		params = new ArrayList();
		fps = new SB_FuncParamSpec("studentId", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fps);
		fs = new SB_FuncSpec("Grade", 132, SB_VarType.kInteger, params);
		preds.add(fs);

		// MyId : entity
		params = new ArrayList();
		fs = new SB_FuncSpec("MyId", 133, SB_VarType.kEntity, params);
		preds.add(fs);

		// NeededDocument : string
		params = new ArrayList();
		fs = new SB_FuncSpec("NeededDocument", 135, SB_VarType.kString, params);
		preds.add(fs);

		// OutOfFilm : boolean
		params = new ArrayList();
		fs = new SB_FuncSpec("OutOfFilm", 130, SB_VarType.kBoolean, params);
		preds.add(fs);

		return preds;
	}

	public String getActionName(int actionId)
	{
		switch (actionId)
		{
		case ACTION_BuyFood:
			return "BuyFood";
		case ACTION_DriveTo:
			return "DriveTo";
		case ACTION_Eat:
			return "Eat";
		case ACTION_FindNewBulb:
			return "FindNewBulb";
		case ACTION_PackSuitcases:
			return "PackSuitcases";
		case ACTION_Print:
			return "Print";
		case ACTION_ReloadCamera:
			return "ReloadCamera";
		case ACTION_ScrewInBulb:
			return "ScrewInBulb";
		case ACTION_TakePhoto:
			return "TakePhoto";
		case ACTION_UnscrewBulb:
			return "UnscrewBulb";
		default:
			// unknown action
			return "";
		}
	}

	public String getPredicateName(int predId)
	{
		switch (predId)
		{
		case PRED_ComplementaryColor:
			return "ComplementaryColor";
		case PRED_FindNearest:
			return "FindNearest";
		case PRED_FridgeContents:
			return "FridgeContents";
		case PRED_GetLocation:
			return "GetLocation";
		case PRED_Grade:
			return "Grade";
		case PRED_MyId:
			return "MyId";
		case PRED_NeededDocument:
			return "NeededDocument";
		case PRED_OutOfFilm:
			return "OutOfFilm";
		default:
			// unknown predicate
			return "";
		}
	}

	public void doAction(int actionId, long entityId, ArrayList params) throws SB_Exception
	{
		switch (actionId)
		{
		case ACTION_BuyFood:
			BuyFood(entityId, (SB_Param)params.get(0));
			break;
		case ACTION_DriveTo:
			DriveTo(entityId, (SB_Param)params.get(0));
			break;
		case ACTION_Eat:
			Eat(entityId);
			break;
		case ACTION_FindNewBulb:
			FindNewBulb(entityId);
			break;
		case ACTION_PackSuitcases:
			PackSuitcases(entityId);
			break;
		case ACTION_Print:
			Print(entityId, (SB_Param)params.get(0));
			break;
		case ACTION_ReloadCamera:
			ReloadCamera(entityId);
			break;
		case ACTION_ScrewInBulb:
			ScrewInBulb(entityId, (SB_Param)params.get(0));
			break;
		case ACTION_TakePhoto:
			TakePhoto(entityId, (SB_Param)params.get(0));
			break;
		case ACTION_UnscrewBulb:
			UnscrewBulb(entityId, (SB_Param)params.get(0));
			break;
		default:
			// unknown action
			break;
		}
	}

	public SB_Param doPredicate(int predId, long entityId, ArrayList params) throws SB_Exception
	{
		switch (predId)
		{
		case PRED_ComplementaryColor:
			return ComplementaryColor((SB_Param)params.get(0));
		case PRED_FindNearest:
			return FindNearest((SB_Param)params.get(0));
		case PRED_FridgeContents:
			return FridgeContents(entityId);
		case PRED_GetLocation:
			return GetLocation(entityId);
		case PRED_Grade:
			return Grade((SB_Param)params.get(0));
		case PRED_MyId:
			return MyId(entityId);
		case PRED_NeededDocument:
			return NeededDocument(entityId);
		case PRED_OutOfFilm:
			return OutOfFilm(entityId);
		default:
			// unknown predicate
			return new SB_Param();
		}
	}

	// ---- Action Implementations

	/**
	 * Causes the entity to buy the specified food
	 * @param food : string [in]
	 */
	void BuyFood(long entityId, SB_Param food) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Bought some tasty " + food.getString());
		_entityMeals.set((int) entityId, food.getString());
	}

	/**
	 * Causes the entity to drive to the specified virtual
	 * @param destination : string [in]
	 */
	void DriveTo(long entityId, SB_Param destination) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Driving to " + destination.getString());
	}

	/**
	 * Causes the entity to eat the specified virtual
	 */
	void Eat(long entityId) throws SB_Exception
	{
		if (_entityMeals.get((int) entityId).equals(""))
		{
			System.out.println("ENTITY " + entityId + ": The fridge is empty!");
		}
		else
		{
			System.out.println("ENTITY " + entityId + ": Ate some " + _entityMeals.get((int) entityId));
		}
	}

	/**
	 * Causes the entity to retrieve a new virtual light bulb for its
	 * kitchen.
	 */
	void FindNewBulb(long entityId) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Bought new light bulb.");
	}

	/**
	 * Causes the entity to pack its virtual suitcases for a
	 */
	void PackSuitcases(long entityId) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Packed suitcases for trip.");
	}

	/**
	 * Prints the specified message to the console
	 * @param message : string [in]
	 */
	void Print(long entityId, SB_Param message) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": " + message.getString());
	}

	/**
	 * Puts a new roll of film in the entity's
	 */
	void ReloadCamera(long entityId) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Put new roll of film in camera");
		_entityFilm.set((int) entityId, new Integer(24));	
	}

	/**
	 * Causes the entity to screw in a light bulb in its virtual
	 * kitchen.
	 * @param whichBulb : integer [in]
	 */
	void ScrewInBulb(long entityId, SB_Param whichBulb) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Screwing in light bulb #" + whichBulb.getInteger());
	}

	/**
	 * Causes the entity to take a photograph of the specified
	 * @param target : string [in]
	 */
	void TakePhoto(long entityId, SB_Param target) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Took picture of " + target.getString());
		int n = ((Integer) _entityFilm.get((int) entityId)).intValue();
		--n;
		_entityFilm.set((int) entityId, new Integer(n));
	}

	/**
	 * Unscrews a single bulb in the entity's virtual
	 * @param whichBulb : integer [in]
	 */
	void UnscrewBulb(long entityId, SB_Param whichBulb) throws SB_Exception
	{
		System.out.println("ENTITY " + entityId + ": Unscrewing light bulb #" + whichBulb.getInteger());
	}

	// ---- Predicate Implementations

	/**
	 * Determines the complementary color for the specified
	 * @param color : string [in]
	 * @return string
	 */
	SB_Param ComplementaryColor(SB_Param color) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		String text = color.getString();
		if (text.equals("red"))
			retVal.setString("green");
		else if (text.equals("green"))
			retVal.setString("red");
		else if (text.equals("blue"))
			retVal.setString("yellow");
		else if (text.equals("yellow"))
			retVal.setString("blue");
		else if (text.equals("purple"))
			retVal.setString("orange");
		else if (text.equals("orange"))
			retVal.setString("purple");
		return retVal;
	}

	/**
	 * Returns the location of the nearest object of the specified
	 * @param whatToFind : string [in]
	 * @return vector
	 */
	SB_Param FindNearest(SB_Param whatToFind) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		String text = whatToFind.getString();
		if (text.equals("grocery"))
			retVal.setVector(10,20,30);
		else if (text.equals("drugstore"))
			retVal.setVector(13,9,25);
		else if (text.equals("restaurant"))
			retVal.setVector(52,12,25);
		return retVal;
	}

	/**
	 * Returns the contents of the entity's virtual refrigerator, or ""
	 * if it is currently
	 * @return string
	 */
	SB_Param FridgeContents(long entityId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		retVal.setString((String) _entityMeals.get((int) entityId));
		return retVal;
	}

	/**
	 * Returns the current location of this
	 * @return string
	 */
	SB_Param GetLocation(long entityId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		switch ((int) entityId)
		{
		case 0: retVal.setString("mall"); break;
		case 1: retVal.setString("pet store"); break;
		default: retVal.setString("grocery"); break;
		}
		return retVal;
	}

	/**
	 * Returns the current grade of the student with the given student
	 * ID
	 * @param studentId : integer [in]
	 * @return integer
	 */
	SB_Param Grade(SB_Param studentId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		retVal.setInteger( 25 * studentId.getInteger() );
		return retVal;
	}

	/**
	 * Returns the ID of the current
	 * @return entity
	 */
	SB_Param MyId(long entityId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		retVal.setInteger((int) entityId);
		return retVal;
	}

	/**
	 * Returns the name of the essential document needed by this entity
	 * to complete his
	 * @return string
	 */
	SB_Param NeededDocument(long entityId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		switch ((int) entityId)
		{
		case 0: retVal.setString("marketing plan"); break;
		case 1: retVal.setString("system architecture"); break;
		default: retVal.setString("sales figures"); break;
		}
		return retVal;
	}

	/**
	 * Returns true if the entity's camera is out of film, false
	 * otherwise.
	 * @return boolean
	 */
	SB_Param OutOfFilm(long entityId) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		int n = ((Integer) _entityFilm.get((int) entityId)).intValue();
		retVal.setBoolean( n == 0 );
		return retVal;
	}
	
	/**
	 * Not necessary for SimBionic.  This method simply initializes our fake "simulation"
	 * for the specified entity.  If we had a real simulation or game, this would be
	 * done there.
	 */
	void initializeSimState(long entityId)
	{
		// initialize the entity's refrigerator
		if (entityId >= _entityMeals.size())
		{
			_entityMeals.setSize((int) entityId + 1);
			// refrigerator starts out empty
			_entityMeals.set((int) entityId, ""); 
		}

		// initialize the entity's camera
		if (entityId >= _entityFilm.size())
		{
			_entityFilm.setSize((int) entityId + 1);
			// camera starts out almost empty
			_entityFilm.set((int) entityId, new Integer(2));
		}
	}
};
